package com.ontheroad.mysql.leanCloud.service;


import com.alibaba.fastjson.JSONObject;
import com.avos.avoscloud.*;
import com.google.common.collect.Lists;
import com.ontheroad.core.util.ConfigProperty;
import com.ontheroad.group.model.GroupModel;
import com.ontheroad.group.service.GroupService;
import com.ontheroad.leanCloud.model.DeviceType;
import com.ontheroad.leanCloud.service.LeanCloudService;
import com.ontheroad.user.model.UserModel;
import com.ontheroad.user.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.ontheroad.leanCloud.model.DeviceType.ANDROID;
import static com.ontheroad.leanCloud.model.DeviceType.IOS;

/**
 * Created by kedong on 2017/11/11 0011.
 */
@Service
public class LeanCloudServiceImpl implements LeanCloudService {

    private static Logger log = LoggerFactory.getLogger(LeanCloudServiceImpl.class);

    @Autowired
    private MessageSource messageSource;
    @Autowired
    private UserService userService;
    @Autowired
    private GroupService groupService;

    private final String CLASS_NAME = "_Conversation";


    static {
        log.info("---------------------------------初始化avos推送服务");
        String appId = ConfigProperty.getProperty("leanCloud.appId");
        String appKey = ConfigProperty.getProperty("leanCloud.appKey");
        String appMaster = ConfigProperty.getProperty("leanCloud.appMasterKey");
        AVOSCloud.initialize(appId, appKey, appMaster);
        AVOSCloud.setDebugLogEnabled(true);
    }

    @Override
    public String getAppId() {
        return messageSource.getMessage("leanCloud.appId", null, null);
    }

    @Override
    public String getAppKey() {
        return messageSource.getMessage("leanCloud.appKey", null, null);
    }

    @Override
    public String getMasterKey() {
        return messageSource.getMessage("leanCloud.appMasterKey", null, null);
    }

    @Override
    public String createSession(String sessionName, JSONObject json, ArrayList<Integer> userIds) throws Exception {
        if (StringUtils.isBlank(sessionName) || userIds == null)
            throw new NullPointerException("会话名称【sessionName】或者用户ID列表【userIds】不能为空");
        if (userIds.size() == 0)
            throw new IllegalArgumentException("【userIds】 长度必须大于0");

        Set<String> ids = new HashSet<>();
        for (Integer userId : userIds) {
            ids.add(userId.toString());
        }
        AVObject conversation = new AVObject(CLASS_NAME);
        conversation.put("name", sessionName);
        conversation.put("m", ids);
        conversation.put("attr", json);
        conversation.save();

        String objectId = conversation.getObjectId();

        if (StringUtils.isEmpty(objectId)) {
            throw new NullPointerException("会话ID【objectId】是空的，创建会话失败");
        }

        List<UserModel> users = userService.findByIds(userIds);
        if (users != null && users.size() > 0) {
            for (UserModel user : users) {
                GroupModel group = new GroupModel();
                group.setCreateTime(new Date());
                group.setObjectId(objectId);
                group.setUserId(user.getId());
                group.setClientId(user.getClientId());
                groupService.insert(group);
            }
        }

        return objectId;
    }


    /**
     * 推送
     *
     * @param content
     * @param deviceType
     * @param map
     * @throws Exception
     */
    @Override
    public void push(String content, DeviceType deviceType, Map<String, Object> map) throws Exception {

        AVPush push = new AVPush();
        map.put("alert", JSONObject.toJSONString(map));
        if (ANDROID.equals(deviceType)) {
            push.setPushToAndroid(true);
        } else if (IOS.equals(deviceType)) {
            push.setPushToIOS(true);
        }

        push.setData(map);
        push.sendInBackground(new SendCallback() {
            @Override
            public void done(AVException e) {
                if (e == null) {
                    log.info("消息推送成功");
                } else {
                    log.error("消息推送失败", e);
                }
            }
        });
    }

    @Override
    public void pushToInstallationId(Integer userId, Map<String, Object> map) {
        AVQuery pushQuery = new AVQuery("_Installation");
        pushQuery.whereEqualTo("userId", userId.toString());
        AVPush push = new AVPush();
        push.setQuery(pushQuery);
        map.put("alert", JSONObject.toJSONString(map));
        push.setData(map);
        push.sendInBackground(new SendCallback() {
            @Override
            public void done(AVException e) {
                if (e == null) {
                    // push successfully.
                    log.info("消息推送成功");
                } else {
                    log.error("消息推送失败", e);
                }
            }
        });
    }

    @Override
    public Boolean addUserToSession(String objectId, Integer userId) {
        try {
            updateSessionUser(objectId, userId, 1);

            GroupModel group = new GroupModel();
            group.setCreateTime(new Date());
            group.setObjectId(objectId);
            group.setUserId(userId);
            groupService.insert(group);

            return true;
        } catch (AVException e) {
            e.printStackTrace();
            log.error("添加用户到群聊中失败：", e);
            return false;
        }
    }

    @Override
    public Boolean removeUserFromSession(String objectId, Integer userId) {
        try {
            updateSessionUser(objectId, userId, 2);
            groupService.delete(objectId, userId);
            return true;
        } catch (AVException e) {
            e.printStackTrace();
            log.error("从群聊中删除用户失败：", e);
            return false;
        }
    }

    private void updateSessionUser(String objectId, Integer userId, Integer actionType) throws AVException {
        AVQuery<AVObject> avQuery = new AVQuery<>(CLASS_NAME);
        AVObject object = avQuery.get(objectId);

        if (actionType == 1) {
            object.addUnique("m", userId.toString());
            object.save();
        } else if (actionType == 2) {
            object.removeAll("m", Lists.newArrayList(userId));
            object.save();
        } else {
            throw new IllegalArgumentException("未知的操作，actionType的取值为：1、添加用户到对话中；2、从对话中删除用户");
        }

    }

}
